package com.mall.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.mall.constant.MessageConstant;
import com.mall.dto.OrderCancelDTO;
import com.mall.dto.OrderConfirmDTO;
import com.mall.dto.OrderRejectionDTO;
import com.mall.dto.OrdersPageQueryDTO;
import com.mall.exception.BaseException;
import com.mall.po.OrderDetail;
import com.mall.po.Orders;
import com.mall.mapper.OrdersMapper;

import com.mall.result.PageResult;

import com.mall.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mall.vo.OrderCountVO;
import com.mall.vo.OrdersVO;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * <p>
 * 订单信息 服务实现类
 * </p>
 *
 * @author itlxc
 * @since 2024-04-28
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    /**
     * 订单搜索
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult ordersPageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        // 查询条件
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<Orders>()
                .like(StringUtils.isNotBlank(ordersPageQueryDTO.getNumber()),
                        Orders::getNumber, ordersPageQueryDTO.getNumber())
                .like(StringUtils.isNotBlank(ordersPageQueryDTO.getPhone()),
                        Orders::getPhone, ordersPageQueryDTO.getPhone())
                .eq(ordersPageQueryDTO.getStatus() != null,
                        Orders::getStatus, ordersPageQueryDTO.getStatus())
                .ge(ordersPageQueryDTO.getBeginTime() != null,
                        Orders::getOrderTime, ordersPageQueryDTO.getBeginTime())
                .le(ordersPageQueryDTO.getEndTime() != null,
                        Orders::getOrderTime, ordersPageQueryDTO.getEndTime())
                .orderByDesc(Orders::getOrderTime);
        // 分页查询
        Page<Orders> page = this.page(new Page<>(ordersPageQueryDTO.getPage(),
                ordersPageQueryDTO.getPageSize()), queryWrapper);
        List<Orders> ordersList = page.getRecords();
        List<OrdersVO> ordersVOList = new ArrayList<>(ordersList.size());
        if (CollUtil.isNotEmpty(ordersList)) {
            // 获取所有订单id
            List<Long> ids = ordersList.stream().map(Orders::getId).collect(Collectors.toList());
            // 查询订单详情
            List<OrderDetail> orderDetailList = Db.lambdaQuery(OrderDetail.class)
                                                    .in(OrderDetail::getOrderId, ids)
                                                    .list();
            Map<Long, String> collect = new HashMap<>(0);
            if (CollUtil.isNotEmpty(orderDetailList)) {
                // 订单id分组
                collect = orderDetailList.stream()
                        .collect(groupingBy(OrderDetail::getOrderId,
                                mapping(orderDetail -> orderDetail.getName() + "*" + orderDetail.getNumber() + ";", joining(""))));
            }
            Map<Long, String> finalCollect = collect;
            ordersList.forEach(orders -> {
                OrdersVO ordersVO = BeanUtil.copyProperties(orders, OrdersVO.class);
                String orderGoods = finalCollect.get(orders.getId());
                ordersVO.setOrderGoods(orderGoods);
                ordersVOList.add(ordersVO);
            });
        }
        return new PageResult(page.getTotal(), ordersVOList);
    }

    /**
     * 各个状态的订单数量统计
     * @return
     */
    @Override
    public OrderCountVO getStatistics() {
        // 待接单数量
        Long toBeConfirmed = lambdaQuery().eq(Orders::getStatus, Orders.TO_BE_CONFIRMED).count();
        // 待派送数量
        Long confirmed = lambdaQuery().eq(Orders::getStatus, Orders.CONFIRMED).count();
        // 派送中数量
        Long deliveryInProgress = lambdaQuery().eq(Orders::getStatus, Orders.DELIVERY_IN_PROGRESS).count();
        return OrderCountVO.builder()
                .toBeConfirmed(toBeConfirmed)
                .confirmed(confirmed)
                .deliveryInProgress(deliveryInProgress)
                .build();
    }

    /**
     * 商家接单
     * @param orderConfirmDTO
     */
    @Override
    public void confirmOrders(OrderConfirmDTO orderConfirmDTO) {
        Orders orderDB = getById(orderConfirmDTO.getId());
        // 判断订单是否存在
        if (Objects.isNull(orderDB)) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }
        // 判断订单状态是否为待接单
        if (!Objects.equals(orderDB.getStatus(), Orders.TO_BE_CONFIRMED)) {
            throw new BaseException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Orders orders = Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.CONFIRMED)
                        .build();
        // 更新订单状态
        updateById(orders);
    }

    /**
     * 商家拒单
     * @param orderRejectionDTO
     */
    @Override
    public void rejectionOrders(OrderRejectionDTO orderRejectionDTO) {
        // 判断订单是否存在
        Orders orderDB = getById(orderRejectionDTO.getId());
        if (Objects.isNull(orderDB)) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 判断订单状态是否为待接单
        if (!Objects.equals(orderDB.getStatus(), Orders.TO_BE_CONFIRMED)) {
            throw new BaseException(MessageConstant.ORDER_STATUS_ERROR);
        }

        Orders orders = Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.CANCELLED)
                        .payStatus(Orders.REFUND)
                        .rejectionReason(orderRejectionDTO.getRejectionReason())
                        .build();

        // 更新订单状态
        updateById(orders);
    }

    /**
     * 派送订单
     * @param id
     */
    @Override
    public void deliveryOrders(Long id) {
        Orders orderDB = getById(id);
        // 判断订单是否存在
        if (Objects.isNull(orderDB)) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 判断订单状态是否为商家已接单
        if (!Objects.equals(orderDB.getStatus(), Orders.CONFIRMED)) {
            throw new BaseException(MessageConstant.ORDER_STATUS_ERROR);
        }

        Orders orders = Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.DELIVERY_IN_PROGRESS)
                        .build();

        // 更新订单状态
        updateById(orders);
    }

    /**
     * 完成订单
     * @param id
     */
    @Override
    public void completeOrders(Long id) {
        // 判断订单是否存在
        Orders orderDB = getById(id);
        if (Objects.isNull(orderDB)) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }
        // 判断订单状态是否为派送中
        if (!Objects.equals(orderDB.getStatus(), Orders.DELIVERY_IN_PROGRESS)) {
            throw new BaseException(MessageConstant.ORDER_STATUS_ERROR);
        }
        // 更新订单状态
        Orders orders = Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.COMPLETED)
                        .deliveryTime(LocalDateTime.now())
                        .build();
        updateById(orders);
    }

    /**
     * 商家取消订单
     * @param orderCancelDTO
     */
    @Override
    public void cancelOrders(OrderCancelDTO orderCancelDTO) {
        // 判断订单是否存在
        Orders orderDB = getById(orderCancelDTO.getId());
        if (Objects.isNull(orderDB)) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }

        // 只有已接单和派送中才能取消订单
        if (!(orderDB.getStatus() > Orders.TO_BE_CONFIRMED &&
                orderDB.getStatus() < Orders.COMPLETED)) {
            throw new BaseException(MessageConstant.ORDER_STATUS_ERROR);
        }
        // 更新订单状态
        Orders orders = Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.CANCELLED)
                        .payStatus(Orders.REFUND)
                        .cancelReason(orderCancelDTO.getCancelReason())
                        .cancelTime(LocalDateTime.now())
                        .build();

        updateById(orders);
    }
}
